﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;

namespace PokemonRPG
{
    public class Camera
    {
        public Matrix View { get; private set; }
        public Matrix Projection { get; set; }
        Vector3 position, center, target, up;
        float radius, rotationX, rotationY;

        public Vector3 Center { get { return center; } }

        public Ray DirectionRay
        {
            get
            {
                Vector3 forward = target - position;
                forward.Normalize();
                Ray direction = new Ray(position, forward);
                return direction;
            }
        }

        public Camera(Matrix projM, Vector3 centerV, float rad, float rotX, float rotY)
        {
            Projection = projM;
            center = centerV;
            radius = rad;
            rotationX = rotX;
            rotationY = rotY + MathHelper.Pi;
            up = Vector3.Up;

            Update();
        }

        public void Update()
        {
            target.Y = (float)Math.Sin(rotationX) + center.Y;
            target.X = (float)Math.Sin(rotationY) * (float)Math.Cos(rotationX) + center.X;
            target.Z = (float)Math.Cos(rotationY) * (float)Math.Cos(rotationX) + center.Z;

            position.Y = -radius * (float)Math.Sin(rotationX) + center.Y;
            position.X = -radius * (float)Math.Sin(rotationY) * (float)Math.Cos(rotationX) + center.X;
            position.Z = -radius * (float)Math.Cos(rotationY) * (float)Math.Cos(rotationX) + center.Z;

            View = Matrix.CreateLookAt(position, target, up);
        }

        public void Move(Vector2 delta, float? yClamp = null)
        {
            var direction2 = Vector3.Normalize(new Vector3(target.X - center.X, 0, target.Z - center.Z));
            var direction3 = Vector3.Normalize(target - center);

            center += (yClamp.HasValue ? direction2 : direction3) * delta.Y;

            center.X += -direction2.Z * delta.X;
            center.Z += direction2.X * delta.X;

            if (yClamp.HasValue) center.Y = yClamp.Value;
        }

        public void Look(Vector2 delta)
        {
            rotationX += delta.Y;
            rotationY -= delta.X;
            rotationX = MathHelper.Clamp(rotationX, -1.57f, 1.57f);
        }
    }
}
